purpose of notebook

(-) describe & visualize relationship between variables (multivariate) (-) correlation plots (-) gather interesting observations for further investigation (-) gather possible new features for extraction

todos: (-) …

information
https://www.kaggle.com/sobhanmoosavi/us-weather-events https://smoosavi.org/datasets/lstw
Moosavi, Sobhan, Mohammad Hossein Samavatian, Arnab Nandi, Srinivasan Parthasarathy, and Rajiv Ramnath. “Short and Long-term Pattern Discovery Over Large-Scale Geo-Spatiotemporal Data.” In Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining, ACM, 2019.
Weather event is a spatiotemporal entity, where such an entity is associated with location and time. Following is the description of available weather event types:
Severe-Cold: The case of having extremely low temperature, with temperature below -23.7 degrees of Celsius. Fog: The case where there is low visibility condition as a result of fog or haze. Hail: The case of having solid precipitation including ice pellets and hail. Rain: The case of having rain, ranging from light to heavy. Snow: The case of having snow, ranging from light to heavy. Storm: The extremely windy condition, where the wind speed is at least 60 km/h. Other Precipitation: Any other type of precipitation which cannot be assigned to previously described event types.
The weather data is provided in terms of a CSV file with the following attributes: Attribute Description Nullable 1 EventId This is the identifier of a record No 2 Type The type of an event; examples are rain and snow. No 3 Severity The severity of an event, wherever applicable. Yes 4 StartTime (UTC) The start time of an event in UTC time zone. No 5 EndTime (UTC) The end time of an event in UTC time zone. No 6 TimeZone The US-based timezone based on the location of an event No (eastern, central, mountain, and pacific). 7 LocationLat The latitude in GPS coordinate. Yes 8 LocationLng The longitude in GPS coordinate. Yes 9 AirportCode The airport station that a weather event is reported from. Yes 10 City The city in address record. Yes 11 County The county in address record. Yes 12 State The state in address record. Yes 13 ZipCode The zipcode in address record. Yes

insights

  1. we can see the waves in the frequency of the events, but it seems that the duration is stable / constant, except for Los Angeles; may be the events are a little longer over the years on average
  2. Snow comes in seasons in New York and Seattle of course, but cold seem to increase in New York and Los Angeles since 2019 and not stick to winter season; Fog is mostly in Los Angeles and also increasing since 2019, Rain is present is all cities all the year, Seattle seems to have waves / seasons of Rain, and Los Angeles hast most year almost no Rain with spikes, funny is that in overall plot per city the snow seasons in New York did not really show, but in Seattle they really do, maybe since they sync with rain waves
  3. Severe events seem to increase since 2019, which might be Fog in Los Angeles
  4. can’t quite find the reason why there is so much reporting at specific fixed minutes, might be automated but trigger is unknown, but there is an interesting pattern here, might be because of recording method
  5. Houston has constant Rain and less Fog in Summer; Los Angeles has no Rain in Summer, but constant Fog and also Cold; New York has constant Rain and Fog, Snow in Winter, Cold also all Year; Seattle has less Rain in Summer, Fog and Snow in Winter
  6. Fog seems to have starting hours (and end): Houston 9 - 12 to 13 - 14, Los Angeles 14 - 16 to 15 - 19, New York 12 - 14 to 14 - 16, Seattle 13 - 16 to 15 - 18 all others are constant across hours of day
  7. Houston stable over years, Los Angeles increased Cold and Fog, New York mostly stable, but jump 2019 in Cold, Seattle little increase in Fog and decrease in Snow
stories

(!) compare 4 big cities which are all close to the coast but vary in significantly in longitude and latitude

load packages
overview
head(weather)
summary(weather)
   EventId                     Type          Severity      StartTime                      EndTime                          TimeZone     LocationLat     LocationLng     
 Length:12226       Cold         : 365   Heavy   : 439   Min.   :2016-01-01 08:47:00   Min.   :2016-01-01 09:47:00   US/Central:2900   Min.   :29.98   Min.   :-122.31  
 Class :character   Fog          :2920   Light   :6792   1st Qu.:2017-04-08 08:59:45   1st Qu.:2017-04-08 11:06:30   US/Eastern:3656   1st Qu.:34.02   1st Qu.:-122.31  
 Mode  :character   Hail         :   6   Moderate:3428   Median :2018-09-27 02:42:30   Median :2018-09-27 03:02:30   US/Pacific:5670   Median :40.78   Median : -95.36  
                    Precipitation: 139   Other   :   6   Mean   :2018-08-09 22:18:52   Mean   :2018-08-09 23:49:14                     Mean   :38.70   Mean   :-100.68  
                    Rain         :8296   Severe  :1422   3rd Qu.:2019-11-24 10:37:30   3rd Qu.:2019-11-24 12:37:30                     3rd Qu.:47.44   3rd Qu.: -73.97  
                    Snow         : 494   UNK     : 139   Max.   :2020-12-31 23:22:00   Max.   :2020-12-31 23:53:00                     Max.   :47.44   Max.   : -73.97  
                    Storm        :   6                                                                                                                                  
          City        Duration       
 Houston    :2900   Length:12226     
 Los Angeles:2378   Class :difftime  
 New York   :3656   Mode  :numeric   
 Seattle    :3292                    
                                     
                                     
                                     
multivariate Duration over StartTime

we can see the waves in the frequency of the events, but it seems that the duration is stable / constant, except for Los Angeles; may be the events are a little longer over the years on average

-> is there another plot for seeing the duration over time and verifying it to be mostly constant?

time_duration_plot_point <- weather %>%
  filter(as.numeric(Duration) < 600) %>%
  ggplot(aes(x = StartTime, y = as.numeric(Duration), col = fct_infreq(City))) +
    geom_point(alpha = 0.2, size = 0.5) +
    geom_smooth() +
    theme_minimal() +
    facet_grid(vars(City)) +
    ggtitle("Duration over StartTime")

ggplotly(time_duration_plot_point)
`geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
multivariate Type over StartTime

Snow comes in seasons in New York and Seattle of course, but cold seem to increase in New York and Los Angeles since 2019 and not stick to winter season; Fog is mostly in Los Angeles and also increasing since 2019, Rain is present is all cities all the year, Seattle seems to have waves / seasons of Rain, and Los Angeles hast most year almost no Rain with spikes, funny is that in overall plot per city the snow seasons in New York did not really show, but in Seattle they really do, maybe since they sync with rain waves

time_type_plot_point <- weather %>%
  filter(as.numeric(Duration) < 600) %>%
  ggplot(aes(x = StartTime, y = fct_infreq(Type), col = fct_infreq(City))) +
    geom_jitter(alpha = 0.2, size = 0.5) +
    theme_minimal() +
    # facet_grid(vars(City)) +
    ggtitle("Type over StartTime")

ggplotly(time_type_plot_point)
time_type_plot_freq <- weather %>%
  filter(as.numeric(Duration) < 600) %>%
  ggplot(aes(x = StartTime, col = fct_infreq(City))) +
    geom_freqpoly(alpha = 0.8, bins = 30) +
    theme_minimal() +
    facet_grid(vars(fct_infreq(Type))) +
    ggtitle("Type over StartTime")

ggplotly(time_type_plot_freq)
multivariate Severity over StartTime

Severe events seem to increase since 2019, which might be Fog in Los Angeles

time_severity_plot_point <- weather %>%
  filter(as.numeric(Duration) < 600) %>%
  ggplot(aes(x = StartTime, y = fct_infreq(Severity), col = fct_infreq(City))) +
    geom_jitter(alpha = 0.2, size = 0.5) +
    theme_minimal() +
    # facet_grid(vars(City)) +
    ggtitle("Severity over StartTime")

ggplotly(time_severity_plot_point)
time_severity_plot_freq <- weather %>%
  filter(as.numeric(Duration) < 600) %>%
  ggplot(aes(x = StartTime, col = fct_infreq(City))) +
    geom_freqpoly(alpha = 0.8, bins = 30) +
    theme_minimal() +
    facet_grid(vars(fct_infreq(Severity))) +
    ggtitle("Severity over StartTime")

ggplotly(time_severity_plot_freq)
multivariate Duration over Minute

can’t quite find the reason why there is so much reporting at specific fixed minutes, might be automated but trigger is unknown, but there is an interesting pattern here, might be because of recording method

minute_severity_plot_freq <- weather %>%
  filter(as.numeric(Duration) < 600) %>%
  mutate(minute = minute(StartTime)) %>%
  ggplot(aes(x = minute, y = as.numeric(Duration), col = fct_infreq(City))) +
    geom_jitter(alpha = 0.2, size = 0.5) +
    theme_minimal() +
    ggtitle("Severity over Minute")

ggplotly(minute_severity_plot_freq)
multivariate Type over Month

Houston has constant Rain and less Fog in Summer; Los Angeles has no Rain in Summer, but constant Fog and also Cold; New York has constant Rain and Fog, Snow in Winter, Cold also all Year; Seattle has less Rain in Summer, Fog and Snow in Winter

-> I guess there is a better plot for this, but its good for now

month_type_plot_freq <- weather %>%
  mutate(month = month(StartTime, label = TRUE)) %>%
  ggplot(aes(x = month, y = fct_infreq(Type), col = fct_infreq(City))) +
    geom_jitter(alpha = 0.2, size = 0.5) +
    facet_grid(vars(City)) +
    theme_minimal() +
    ggtitle("Type over Month")

ggplotly(month_type_plot_freq)
multivariate Type over Hour

Fog seems to have starting hours (and end): Houston 9 - 12 to 13 - 14, Los Angeles 14 - 16 to 15 - 19, New York 12 - 14 to 14 - 16, Seattle 13 - 16 to 15 - 18 Rain in Houston is also more often starting in the second half of the day all others are constant across hours of day

-> sync for local time zone to understand morning and evening time dependend events

hour_type_plot_freq <- weather %>%
  mutate(hour = hour(StartTime)) %>%
  ggplot(aes(x = hour, y = fct_infreq(Type), col = fct_infreq(City))) +
    geom_jitter(alpha = 0.2, size = 0.5) +
    facet_grid(vars(City)) +
    theme_minimal() +
    ggtitle("Type over Hour")

hour_type_plot_bar <- weather %>%
  mutate(hour = hour(StartTime)) %>%
  ggplot(aes(x = hour, fill = fct_infreq(Type))) +
       geom_bar(position = position_dodge(preserve = "single")) +
    facet_grid(vars(City)) +
    theme_minimal() +
    ggtitle("Type over Start Hour")

ggplotly(hour_type_plot_freq)
ggplotly(hour_type_plot_bar)
position_dodge requires non-overlapping x intervalsposition_dodge requires non-overlapping x intervals
hour_type_plot_freq <- weather %>%
  mutate(hour = hour(EndTime)) %>%
  ggplot(aes(x = hour, y = fct_infreq(Type), col = fct_infreq(City))) +
    geom_jitter(alpha = 0.2, size = 0.5) +
    facet_grid(vars(City)) +
    theme_minimal() +
    ggtitle("Type over Hour")

hour_type_plot_bar <- weather %>%
  mutate(hour = hour(EndTime)) %>%
  ggplot(aes(x = hour, fill = fct_infreq(Type))) +
       geom_bar(position = position_dodge(preserve = "single")) +
    facet_grid(vars(City)) +
    theme_minimal() +
    ggtitle("Type over End Hour")

ggplotly(hour_type_plot_freq)
ggplotly(hour_type_plot_bar)
position_dodge requires non-overlapping x intervalsposition_dodge requires non-overlapping x intervalsposition_dodge requires non-overlapping x intervals
multivariate Type over Year

Houston stable over years, Los Angeles increased Cold and Fog, New York mostly stable, but jump 2019 in Cold, Seattle little increase in Fog and decrease in Snow

year_type_plot_freq <- weather %>%
  mutate(year = year(StartTime)) %>%
  ggplot(aes(x = year, y = fct_infreq(Type), col = fct_infreq(City))) +
    geom_jitter(alpha = 0.2, size = 0.5) +
    facet_grid(vars(City)) +
    theme_minimal() +
    ggtitle("Type over Year")

ggplotly(year_type_plot_freq)
year_type_plot_freq <- weather %>%
  mutate(year = year(StartTime)) %>%
  ggplot(aes(x = year, fill = fct_infreq(Type))) +
    geom_bar(position = position_dodge(preserve = "single")) +
    facet_grid(vars(City)) +
    theme_minimal() +
    ggtitle("Type over Year")

ggplotly(year_type_plot_freq)
position_dodge requires non-overlapping x intervals
LS0tDQp0aXRsZTogImRlc2NyaWJlIGFuZCB2aXN1YWxpemUgb2YgVVMgd2VhdGhlciBldmVudCBkYXRhIg0Kc3VidGl0bGU6ICJjaXR5IHNlbGVjdGlvbiAtIG11bHRpdmFyaWF0ZSBmb3IgdGltZSB2YXJpYWJsZXMiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQotLS0NCnB1cnBvc2Ugb2Ygbm90ZWJvb2sNCi0tLQ0KDQogICgtKSBkZXNjcmliZSAmIHZpc3VhbGl6ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB2YXJpYWJsZXMgKG11bHRpdmFyaWF0ZSkNCiAgKC0pIGNvcnJlbGF0aW9uIHBsb3RzIA0KICAoLSkgZ2F0aGVyIGludGVyZXN0aW5nIG9ic2VydmF0aW9ucyBmb3IgZnVydGhlciBpbnZlc3RpZ2F0aW9uDQogICgtKSBnYXRoZXIgcG9zc2libGUgbmV3IGZlYXR1cmVzIGZvciBleHRyYWN0aW9uDQogIA0KdG9kb3M6DQogICgtKSAuLi4NCg0KLS0tDQppbmZvcm1hdGlvbg0KLS0tDQpodHRwczovL3d3dy5rYWdnbGUuY29tL3NvYmhhbm1vb3NhdmkvdXMtd2VhdGhlci1ldmVudHMNCmh0dHBzOi8vc21vb3Nhdmkub3JnL2RhdGFzZXRzL2xzdHcNCg0KTW9vc2F2aSwgU29iaGFuLCBNb2hhbW1hZCBIb3NzZWluIFNhbWF2YXRpYW4sIEFybmFiIE5hbmRpLCBTcmluaXZhc2FuIFBhcnRoYXNhcmF0aHksIGFuZCBSYWppdiBSYW1uYXRoLiDigJxTaG9ydCBhbmQgTG9uZy10ZXJtIFBhdHRlcm4gRGlzY292ZXJ5IE92ZXIgTGFyZ2UtU2NhbGUgR2VvLVNwYXRpb3RlbXBvcmFsIERhdGEu4oCdIEluIFByb2NlZWRpbmdzIG9mIHRoZSAyNXRoIEFDTSBTSUdLREQgSW50ZXJuYXRpb25hbCBDb25mZXJlbmNlIG9uIEtub3dsZWRnZSBEaXNjb3ZlcnkgJiBEYXRhIE1pbmluZywgQUNNLCAyMDE5Lg0KDQpXZWF0aGVyIGV2ZW50IGlzIGEgc3BhdGlvdGVtcG9yYWwgZW50aXR5LCB3aGVyZSBzdWNoIGFuIGVudGl0eSBpcyBhc3NvY2lhdGVkIHdpdGggbG9jYXRpb24gYW5kIHRpbWUuIEZvbGxvd2luZyBpcyB0aGUgZGVzY3JpcHRpb24gb2YgYXZhaWxhYmxlIHdlYXRoZXIgZXZlbnQgdHlwZXM6DQoNCiAgICBTZXZlcmUtQ29sZDogVGhlIGNhc2Ugb2YgaGF2aW5nIGV4dHJlbWVseSBsb3cgdGVtcGVyYXR1cmUsIHdpdGggdGVtcGVyYXR1cmUgYmVsb3cgLTIzLjcgZGVncmVlcyBvZiBDZWxzaXVzLg0KICAgIEZvZzogVGhlIGNhc2Ugd2hlcmUgdGhlcmUgaXMgbG93IHZpc2liaWxpdHkgY29uZGl0aW9uIGFzIGEgcmVzdWx0IG9mIGZvZyBvciBoYXplLg0KICAgIEhhaWw6IFRoZSBjYXNlIG9mIGhhdmluZyBzb2xpZCBwcmVjaXBpdGF0aW9uIGluY2x1ZGluZyBpY2UgcGVsbGV0cyBhbmQgaGFpbC4NCiAgICBSYWluOiBUaGUgY2FzZSBvZiBoYXZpbmcgcmFpbiwgcmFuZ2luZyBmcm9tIGxpZ2h0IHRvIGhlYXZ5Lg0KICAgIFNub3c6IFRoZSBjYXNlIG9mIGhhdmluZyBzbm93LCByYW5naW5nIGZyb20gbGlnaHQgdG8gaGVhdnkuDQogICAgU3Rvcm06IFRoZSBleHRyZW1lbHkgd2luZHkgY29uZGl0aW9uLCB3aGVyZSB0aGUgd2luZCBzcGVlZCBpcyBhdCBsZWFzdCA2MCBrbS9oLg0KICAgIE90aGVyIFByZWNpcGl0YXRpb246IEFueSBvdGhlciB0eXBlIG9mIHByZWNpcGl0YXRpb24gd2hpY2ggY2Fubm90IGJlIGFzc2lnbmVkIHRvIHByZXZpb3VzbHkgZGVzY3JpYmVkIGV2ZW50IHR5cGVzLg0KDQpUaGUgd2VhdGhlciBkYXRhIGlzIHByb3ZpZGVkIGluIHRlcm1zIG9mIGEgQ1NWIGZpbGUgd2l0aCB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6DQogICAgICBBdHRyaWJ1dGUJICAgICAgICBEZXNjcmlwdGlvbgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdWxsYWJsZQ0KMQkgICAgRXZlbnRJZAkgICAgICAgICAgVGhpcyBpcyB0aGUgaWRlbnRpZmllciBvZiBhIHJlY29yZAkgICAgICAgICAgICAgICAgICAgICAgICBObw0KMiAgIAlUeXBlCSAgICAgICAgICAgIFRoZSB0eXBlIG9mIGFuIGV2ZW50OyBleGFtcGxlcyBhcmUgcmFpbiBhbmQgc25vdy4JICAgICAgICAgIE5vDQozCSAgICBTZXZlcml0eQkgICAgICAgIFRoZSBzZXZlcml0eSBvZiBhbiBldmVudCwgd2hlcmV2ZXIgYXBwbGljYWJsZS4gICAgICAgIAkgICAgWWVzDQo0CSAgICBTdGFydFRpbWUgKFVUQykJICBUaGUgc3RhcnQgdGltZSBvZiBhbiBldmVudCBpbiBVVEMgdGltZSB6b25lLiAgICAgICAgICAJICAgIE5vDQo1CSAgICBFbmRUaW1lIChVVEMpCSAgICBUaGUgZW5kIHRpbWUgb2YgYW4gZXZlbnQgaW4gVVRDIHRpbWUgem9uZS4JICAgICAgICAgICAgICAgIE5vDQo2CSAgICBUaW1lWm9uZQkgICAgICAgIFRoZSBVUy1iYXNlZCB0aW1lem9uZSBiYXNlZCBvbiB0aGUgbG9jYXRpb24gb2YgYW4gZXZlbnQgICAgIE5vDQogICAgICAgICAgICAgICAgICAgICAgICAoZWFzdGVybiwgY2VudHJhbCwgbW91bnRhaW4sIGFuZCBwYWNpZmljKS4JDQo3CSAgICBMb2NhdGlvbkxhdAkgICAgICBUaGUgbGF0aXR1ZGUgaW4gR1BTIGNvb3JkaW5hdGUuCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBZZXMNCjggICAJTG9jYXRpb25MbmcJICAgICAgVGhlIGxvbmdpdHVkZSBpbiBHUFMgY29vcmRpbmF0ZS4JICAgICAgICAgICAgICAgICAgICAgICAgICBZZXMNCjkJICAgIEFpcnBvcnRDb2RlCSAgICAgIFRoZSBhaXJwb3J0IHN0YXRpb24gdGhhdCBhIHdlYXRoZXIgZXZlbnQgaXMgcmVwb3J0ZWQgZnJvbS4JWWVzDQoxMAkgIENpdHkJICAgICAgICAgICAgVGhlIGNpdHkgaW4gYWRkcmVzcyByZWNvcmQuCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQoxMQkgIENvdW50eQkgICAgICAgICAgVGhlIGNvdW50eSBpbiBhZGRyZXNzIHJlY29yZC4JICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQoxMgkgIFN0YXRlCSAgICAgICAgICAgIFRoZSBzdGF0ZSBpbiBhZGRyZXNzIHJlY29yZC4JICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQoxMwkgIFppcENvZGUJICAgICAgICAgIFRoZSB6aXBjb2RlIGluIGFkZHJlc3MgcmVjb3JkLgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQoNCi0tLQ0KaW5zaWdodHMgDQotLS0NCiAgDQogIChpKSB3ZSBjYW4gc2VlIHRoZSB3YXZlcyBpbiB0aGUgZnJlcXVlbmN5IG9mIHRoZSBldmVudHMsIGJ1dCBpdCBzZWVtcyB0aGF0IHRoZSBkdXJhdGlvbiBpcyBzdGFibGUgLyBjb25zdGFudCwgZXhjZXB0IGZvciBMb3MgQW5nZWxlczsNCiAgICAgIG1heSBiZSB0aGUgZXZlbnRzIGFyZSBhIGxpdHRsZSBsb25nZXIgb3ZlciB0aGUgeWVhcnMgb24gYXZlcmFnZQ0KICAoaSkgU25vdyBjb21lcyBpbiBzZWFzb25zIGluIE5ldyBZb3JrIGFuZCBTZWF0dGxlIG9mIGNvdXJzZSwgYnV0IGNvbGQgc2VlbSB0byBpbmNyZWFzZSBpbiBOZXcgWW9yayBhbmQgTG9zIEFuZ2VsZXMgc2luY2UgMjAxOSBhbmQgbm90IHN0aWNrIHRvIHdpbnRlciBzZWFzb247DQogICAgICBGb2cgaXMgbW9zdGx5IGluIExvcyBBbmdlbGVzIGFuZCBhbHNvIGluY3JlYXNpbmcgc2luY2UgMjAxOSwgDQogICAgICBSYWluIGlzIHByZXNlbnQgaXMgYWxsIGNpdGllcyBhbGwgdGhlIHllYXIsIFNlYXR0bGUgc2VlbXMgdG8gaGF2ZSB3YXZlcyAvIHNlYXNvbnMgb2YgUmFpbiwgYW5kIExvcyBBbmdlbGVzIGhhc3QgbW9zdCB5ZWFyIGFsbW9zdCBubyBSYWluIHdpdGggc3Bpa2VzLCANCiAgICAgIGZ1bm55IGlzIHRoYXQgaW4gb3ZlcmFsbCBwbG90IHBlciBjaXR5IHRoZSBzbm93IHNlYXNvbnMgaW4gTmV3IFlvcmsgZGlkIG5vdCByZWFsbHkgc2hvdywgYnV0IGluIFNlYXR0bGUgdGhleSByZWFsbHkgZG8sIG1heWJlIHNpbmNlIHRoZXkgc3luYyB3aXRoIHJhaW4gd2F2ZXMNCiAgKGkpIFNldmVyZSBldmVudHMgc2VlbSB0byBpbmNyZWFzZSBzaW5jZSAyMDE5LCB3aGljaCBtaWdodCBiZSBGb2cgaW4gTG9zIEFuZ2VsZXMNCiAgKGkpIGNhbid0IHF1aXRlIGZpbmQgdGhlIHJlYXNvbiB3aHkgdGhlcmUgaXMgc28gbXVjaCByZXBvcnRpbmcgYXQgc3BlY2lmaWMgZml4ZWQgbWludXRlcywgbWlnaHQgYmUgYXV0b21hdGVkIGJ1dCB0cmlnZ2VyIGlzIHVua25vd24sIA0KICAgICAgYnV0IHRoZXJlIGlzIGFuIGludGVyZXN0aW5nIHBhdHRlcm4gaGVyZSwgbWlnaHQgYmUgYmVjYXVzZSBvZiByZWNvcmRpbmcgbWV0aG9kDQogIChpKSBIb3VzdG9uIGhhcyBjb25zdGFudCBSYWluIGFuZCBsZXNzIEZvZyBpbiBTdW1tZXI7IExvcyBBbmdlbGVzIGhhcyBubyBSYWluIGluIFN1bW1lciwgYnV0IGNvbnN0YW50IEZvZyBhbmQgYWxzbyBDb2xkOyBOZXcgWW9yayBoYXMgY29uc3RhbnQgUmFpbiBhbmQgRm9nLCBTbm93IGluIFdpbnRlciwgQ29sZCAgICAgICAgICBhbHNvIGFsbCBZZWFyOyBTZWF0dGxlIGhhcyBsZXNzIFJhaW4gaW4gU3VtbWVyLCBGb2cgYW5kIFNub3cgaW4gV2ludGVyDQogIChpKSBGb2cgc2VlbXMgdG8gaGF2ZSBzdGFydGluZyBob3VycyAoYW5kIGVuZCk6IEhvdXN0b24gOSAtIDEyIHRvIDEzIC0gMTQsIExvcyBBbmdlbGVzIDE0IC0gMTYgdG8gMTUgLSAxOSwgTmV3IFlvcmsgMTIgLSAxNCB0byAxNCAtIDE2LCBTZWF0dGxlIDEzIC0gMTYgdG8gMTUgLSAxOA0KICAgICAgYWxsIG90aGVycyBhcmUgY29uc3RhbnQgYWNyb3NzIGhvdXJzIG9mIGRheQ0KICAoaSkgSG91c3RvbiBzdGFibGUgb3ZlciB5ZWFycywgTG9zIEFuZ2VsZXMgaW5jcmVhc2VkIENvbGQgYW5kIEZvZywgTmV3IFlvcmsgbW9zdGx5IHN0YWJsZSwgYnV0IGp1bXAgMjAxOSBpbiBDb2xkLCBTZWF0dGxlIGxpdHRsZSBpbmNyZWFzZSBpbiBGb2cgYW5kIGRlY3JlYXNlIGluIFNub3cNCg0KLS0tDQpzdG9yaWVzDQotLS0NCg0KICAoISkgY29tcGFyZSA0IGJpZyBjaXRpZXMgd2hpY2ggYXJlIGFsbCBjbG9zZSB0byB0aGUgY29hc3QgYnV0IHZhcnkgaW4gc2lnbmlmaWNhbnRseSBpbiBsb25naXR1ZGUgYW5kIGxhdGl0dWRlDQoNCi0tLQ0KbG9hZCBwYWNrYWdlcw0KLS0tDQpgYGB7ciBsb2FkIHBhY2thZ2VzLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpICMgdGlkeSBkYXRhIGZyYW1lDQpsaWJyYXJ5KGdndGhlbWVzKSAjIGZvciBleHRyYSBwbG90IHRoZW1lcw0KbGlicmFyeShwbG90bHkpICMgbWFrZSBnZ3Bsb3RzIGludGVyYWN0aXZlDQpsaWJyYXJ5KGx1YnJpZGF0ZSkgIyBmdW5jdGlvbnMgdG8gd29yayB3aXRoIGRhdGUtdGltZXMgYW5kIHRpbWUtc3BhbnMNCmxpYnJhcnkoY29ycnBsb3QpICMgY29ycmVsYXRpb24gcGxvdHMNCmxpYnJhcnkoZ2dtb3NhaWMpICMgZ2VvbV9tb3NhaWMoKSBtb3NhaWMgcGxvdHMgZm9yIGNhdGVnb3JpY2FsIGRhdGENCmBgYA0KDQotLS0NCm92ZXJ2aWV3DQotLS0NCmBgYHtyfQ0KaGVhZCh3ZWF0aGVyKQ0KYGBgDQpgYGB7cn0NCnN1bW1hcnkod2VhdGhlcikNCmBgYA0KDQotLS0NCm11bHRpdmFyaWF0ZSBEdXJhdGlvbiBvdmVyIFN0YXJ0VGltZQ0KLS0tDQp3ZSBjYW4gc2VlIHRoZSB3YXZlcyBpbiB0aGUgZnJlcXVlbmN5IG9mIHRoZSBldmVudHMsIGJ1dCBpdCBzZWVtcyB0aGF0IHRoZSBkdXJhdGlvbiBpcyBzdGFibGUgLyBjb25zdGFudCwgZXhjZXB0IGZvciBMb3MgQW5nZWxlczsNCm1heSBiZSB0aGUgZXZlbnRzIGFyZSBhIGxpdHRsZSBsb25nZXIgb3ZlciB0aGUgeWVhcnMgb24gYXZlcmFnZQ0KDQotPiBpcyB0aGVyZSBhbm90aGVyIHBsb3QgZm9yIHNlZWluZyB0aGUgZHVyYXRpb24gb3ZlciB0aW1lIGFuZCB2ZXJpZnlpbmcgaXQgdG8gYmUgbW9zdGx5IGNvbnN0YW50Pw0KDQpgYGB7cn0NCnRpbWVfZHVyYXRpb25fcGxvdF9wb2ludCA8LSB3ZWF0aGVyICU+JQ0KICBmaWx0ZXIoYXMubnVtZXJpYyhEdXJhdGlvbikgPCA2MDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBTdGFydFRpbWUsIHkgPSBhcy5udW1lcmljKER1cmF0aW9uKSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4yLCBzaXplID0gMC41KSArDQogICAgZ2VvbV9zbW9vdGgoKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICBnZ3RpdGxlKCJEdXJhdGlvbiBvdmVyIFN0YXJ0VGltZSIpDQoNCmdncGxvdGx5KHRpbWVfZHVyYXRpb25fcGxvdF9wb2ludCkNCmBgYA0KDQotLS0NCm11bHRpdmFyaWF0ZSBUeXBlIG92ZXIgU3RhcnRUaW1lDQotLS0NClNub3cgY29tZXMgaW4gc2Vhc29ucyBpbiBOZXcgWW9yayBhbmQgU2VhdHRsZSBvZiBjb3Vyc2UsIGJ1dCBjb2xkIHNlZW0gdG8gaW5jcmVhc2UgaW4gTmV3IFlvcmsgYW5kIExvcyBBbmdlbGVzIHNpbmNlIDIwMTkgYW5kIG5vdCBzdGljayB0byB3aW50ZXIgc2Vhc29uOw0KRm9nIGlzIG1vc3RseSBpbiBMb3MgQW5nZWxlcyBhbmQgYWxzbyBpbmNyZWFzaW5nIHNpbmNlIDIwMTksIA0KUmFpbiBpcyBwcmVzZW50IGlzIGFsbCBjaXRpZXMgYWxsIHRoZSB5ZWFyLCBTZWF0dGxlIHNlZW1zIHRvIGhhdmUgd2F2ZXMgLyBzZWFzb25zIG9mIFJhaW4sIGFuZCBMb3MgQW5nZWxlcyBoYXN0IG1vc3QgeWVhciBhbG1vc3Qgbm8gUmFpbiB3aXRoIHNwaWtlcywgDQpmdW5ueSBpcyB0aGF0IGluIG92ZXJhbGwgcGxvdCBwZXIgY2l0eSB0aGUgc25vdyBzZWFzb25zIGluIE5ldyBZb3JrIGRpZCBub3QgcmVhbGx5IHNob3csIGJ1dCBpbiBTZWF0dGxlIHRoZXkgcmVhbGx5IGRvLCBtYXliZSBzaW5jZSB0aGV5IHN5bmMgd2l0aCByYWluIHdhdmVzDQoNCmBgYHtyfQ0KdGltZV90eXBlX3Bsb3RfcG9pbnQgPC0gd2VhdGhlciAlPiUNCiAgZmlsdGVyKGFzLm51bWVyaWMoRHVyYXRpb24pIDwgNjAwKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gU3RhcnRUaW1lLCB5ID0gZmN0X2luZnJlcShUeXBlKSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMiwgc2l6ZSA9IDAuNSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgIyBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgU3RhcnRUaW1lIikNCg0KZ2dwbG90bHkodGltZV90eXBlX3Bsb3RfcG9pbnQpDQpgYGANCmBgYHtyfQ0KdGltZV90eXBlX3Bsb3RfZnJlcSA8LSB3ZWF0aGVyICU+JQ0KICBmaWx0ZXIoYXMubnVtZXJpYyhEdXJhdGlvbikgPCA2MDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBTdGFydFRpbWUsIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9mcmVxcG9seShhbHBoYSA9IDAuOCwgYmlucyA9IDMwKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoZmN0X2luZnJlcShUeXBlKSkpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgU3RhcnRUaW1lIikNCg0KZ2dwbG90bHkodGltZV90eXBlX3Bsb3RfZnJlcSkNCmBgYA0KDQotLS0NCm11bHRpdmFyaWF0ZSBTZXZlcml0eSBvdmVyIFN0YXJ0VGltZQ0KLS0tDQpTZXZlcmUgZXZlbnRzIHNlZW0gdG8gaW5jcmVhc2Ugc2luY2UgMjAxOSwgd2hpY2ggbWlnaHQgYmUgRm9nIGluIExvcyBBbmdlbGVzDQoNCmBgYHtyfQ0KdGltZV9zZXZlcml0eV9wbG90X3BvaW50IDwtIHdlYXRoZXIgJT4lDQogIGZpbHRlcihhcy5udW1lcmljKER1cmF0aW9uKSA8IDYwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IFN0YXJ0VGltZSwgeSA9IGZjdF9pbmZyZXEoU2V2ZXJpdHkpLCBjb2wgPSBmY3RfaW5mcmVxKENpdHkpKSkgKw0KICAgIGdlb21faml0dGVyKGFscGhhID0gMC4yLCBzaXplID0gMC41KSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICAjIGZhY2V0X2dyaWQodmFycyhDaXR5KSkgKw0KICAgIGdndGl0bGUoIlNldmVyaXR5IG92ZXIgU3RhcnRUaW1lIikNCg0KZ2dwbG90bHkodGltZV9zZXZlcml0eV9wbG90X3BvaW50KQ0KYGBgDQpgYGB7cn0NCnRpbWVfc2V2ZXJpdHlfcGxvdF9mcmVxIDwtIHdlYXRoZXIgJT4lDQogIGZpbHRlcihhcy5udW1lcmljKER1cmF0aW9uKSA8IDYwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IFN0YXJ0VGltZSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX2ZyZXFwb2x5KGFscGhhID0gMC44LCBiaW5zID0gMzApICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGZhY2V0X2dyaWQodmFycyhmY3RfaW5mcmVxKFNldmVyaXR5KSkpICsNCiAgICBnZ3RpdGxlKCJTZXZlcml0eSBvdmVyIFN0YXJ0VGltZSIpDQoNCmdncGxvdGx5KHRpbWVfc2V2ZXJpdHlfcGxvdF9mcmVxKQ0KYGBgDQoNCi0tLQ0KbXVsdGl2YXJpYXRlIER1cmF0aW9uIG92ZXIgTWludXRlDQotLS0NCmNhbid0IHF1aXRlIGZpbmQgdGhlIHJlYXNvbiB3aHkgdGhlcmUgaXMgc28gbXVjaCByZXBvcnRpbmcgYXQgc3BlY2lmaWMgZml4ZWQgbWludXRlcywgbWlnaHQgYmUgYXV0b21hdGVkIGJ1dCB0cmlnZ2VyIGlzIHVua25vd24sIA0KYnV0IHRoZXJlIGlzIGFuIGludGVyZXN0aW5nIHBhdHRlcm4gaGVyZSwgbWlnaHQgYmUgYmVjYXVzZSBvZiByZWNvcmRpbmcgbWV0aG9kDQoNCmBgYHtyfQ0KbWludXRlX3NldmVyaXR5X3Bsb3RfZnJlcSA8LSB3ZWF0aGVyICU+JQ0KICBmaWx0ZXIoYXMubnVtZXJpYyhEdXJhdGlvbikgPCA2MDApICU+JQ0KICBtdXRhdGUobWludXRlID0gbWludXRlKFN0YXJ0VGltZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtaW51dGUsIHkgPSBhcy5udW1lcmljKER1cmF0aW9uKSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMiwgc2l6ZSA9IDAuNSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiU2V2ZXJpdHkgb3ZlciBNaW51dGUiKQ0KDQpnZ3Bsb3RseShtaW51dGVfc2V2ZXJpdHlfcGxvdF9mcmVxKQ0KYGBgDQoNCi0tLQ0KbXVsdGl2YXJpYXRlIFR5cGUgb3ZlciBNb250aA0KLS0tDQpIb3VzdG9uIGhhcyBjb25zdGFudCBSYWluIGFuZCBsZXNzIEZvZyBpbiBTdW1tZXI7IExvcyBBbmdlbGVzIGhhcyBubyBSYWluIGluIFN1bW1lciwgYnV0IGNvbnN0YW50IEZvZyBhbmQgYWxzbyBDb2xkOyBOZXcgWW9yayBoYXMgY29uc3RhbnQgUmFpbiBhbmQgRm9nLCBTbm93IGluIFdpbnRlciwgQ29sZCBhbHNvIGFsbCBZZWFyOyBTZWF0dGxlIGhhcyBsZXNzIFJhaW4gaW4gU3VtbWVyLCBGb2cgYW5kIFNub3cgaW4gV2ludGVyDQoNCi0+IEkgZ3Vlc3MgdGhlcmUgaXMgYSBiZXR0ZXIgcGxvdCBmb3IgdGhpcywgYnV0IGl0cyBnb29kIGZvciBub3cNCg0KYGBge3J9DQptb250aF90eXBlX3Bsb3RfcG9pbnQgPC0gd2VhdGhlciAlPiUNCiAgbXV0YXRlKG1vbnRoID0gbW9udGgoU3RhcnRUaW1lLCBsYWJlbCA9IFRSVUUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSBmY3RfaW5mcmVxKFR5cGUpLCBjb2wgPSBmY3RfaW5mcmVxKENpdHkpKSkgKw0KICAgIGdlb21faml0dGVyKGFscGhhID0gMC4yLCBzaXplID0gMC41KSArDQogICAgZmFjZXRfZ3JpZCh2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgTW9udGgiKQ0KDQpnZ3Bsb3RseShtb250aF90eXBlX3Bsb3RfcG9pbnQpDQpgYGANCg0KLS0tDQptdWx0aXZhcmlhdGUgVHlwZSBvdmVyIEhvdXINCi0tLQ0KRm9nIHNlZW1zIHRvIGhhdmUgc3RhcnRpbmcgaG91cnMgKGFuZCBlbmQpOiBIb3VzdG9uIDkgLSAxMiB0byAxMyAtIDE0LCBMb3MgQW5nZWxlcyAxNCAtIDE2IHRvIDE1IC0gMTksIE5ldyBZb3JrIDEyIC0gMTQgdG8gMTQgLSAxNiwgU2VhdHRsZSAxMyAtIDE2IHRvIDE1IC0gMTgNClJhaW4gaW4gSG91c3RvbiBpcyBhbHNvIG1vcmUgb2Z0ZW4gc3RhcnRpbmcgaW4gdGhlIHNlY29uZCBoYWxmIG9mIHRoZSBkYXkNCmFsbCBvdGhlcnMgYXJlIGNvbnN0YW50IGFjcm9zcyBob3VycyBvZiBkYXkNCg0KLT4gc3luYyBmb3IgbG9jYWwgdGltZSB6b25lIHRvIHVuZGVyc3RhbmQgbW9ybmluZyBhbmQgZXZlbmluZyB0aW1lIGRlcGVuZGVuZCBldmVudHMNCg0KYGBge3J9DQpob3VyX3R5cGVfcGxvdF9mcmVxIDwtIHdlYXRoZXIgJT4lDQogIG11dGF0ZShob3VyID0gaG91cihTdGFydFRpbWUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gaG91ciwgeSA9IGZjdF9pbmZyZXEoVHlwZSksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjIsIHNpemUgPSAwLjUpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIlR5cGUgb3ZlciBIb3VyIikNCg0KaG91cl90eXBlX3Bsb3RfYmFyIDwtIHdlYXRoZXIgJT4lDQogIG11dGF0ZShob3VyID0gaG91cihTdGFydFRpbWUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gaG91ciwgZmlsbCA9IGZjdF9pbmZyZXEoVHlwZSkpKSArDQogICAgICAgZ2VvbV9iYXIocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZShwcmVzZXJ2ZSA9ICJzaW5nbGUiKSkgKw0KICAgIGZhY2V0X2dyaWQodmFycyhDaXR5KSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiVHlwZSBvdmVyIFN0YXJ0IEhvdXIiKQ0KDQpnZ3Bsb3RseShob3VyX3R5cGVfcGxvdF9mcmVxKQ0KZ2dwbG90bHkoaG91cl90eXBlX3Bsb3RfYmFyKQ0KYGBgDQpgYGB7cn0NCmhvdXJfdHlwZV9wbG90X2ZyZXEgPC0gd2VhdGhlciAlPiUNCiAgbXV0YXRlKGhvdXIgPSBob3VyKEVuZFRpbWUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gaG91ciwgeSA9IGZjdF9pbmZyZXEoVHlwZSksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjIsIHNpemUgPSAwLjUpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIlR5cGUgb3ZlciBIb3VyIikNCg0KaG91cl90eXBlX3Bsb3RfYmFyIDwtIHdlYXRoZXIgJT4lDQogIG11dGF0ZShob3VyID0gaG91cihFbmRUaW1lKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGhvdXIsIGZpbGwgPSBmY3RfaW5mcmVxKFR5cGUpKSkgKw0KICAgICAgIGdlb21fYmFyKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UocHJlc2VydmUgPSAic2luZ2xlIikpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIlR5cGUgb3ZlciBFbmQgSG91ciIpDQoNCmdncGxvdGx5KGhvdXJfdHlwZV9wbG90X2ZyZXEpDQpnZ3Bsb3RseShob3VyX3R5cGVfcGxvdF9iYXIpDQpgYGANCg0KLS0tDQptdWx0aXZhcmlhdGUgVHlwZSBvdmVyIFllYXINCi0tLQ0KSG91c3RvbiBzdGFibGUgb3ZlciB5ZWFycywgTG9zIEFuZ2VsZXMgaW5jcmVhc2VkIENvbGQgYW5kIEZvZywgTmV3IFlvcmsgbW9zdGx5IHN0YWJsZSwgYnV0IGp1bXAgMjAxOSBpbiBDb2xkLCBTZWF0dGxlIGxpdHRsZSBpbmNyZWFzZSBpbiBGb2cgYW5kIGRlY3JlYXNlIGluIFNub3cgDQoNCmBgYHtyfQ0KeWVhcl90eXBlX3Bsb3RfZnJlcSA8LSB3ZWF0aGVyICU+JQ0KICBtdXRhdGUoeWVhciA9IHllYXIoU3RhcnRUaW1lKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBmY3RfaW5mcmVxKFR5cGUpLCBjb2wgPSBmY3RfaW5mcmVxKENpdHkpKSkgKw0KICAgIGdlb21faml0dGVyKGFscGhhID0gMC4yLCBzaXplID0gMC41KSArDQogICAgZmFjZXRfZ3JpZCh2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgWWVhciIpDQoNCmdncGxvdGx5KHllYXJfdHlwZV9wbG90X2ZyZXEpDQpgYGANCmBgYHtyfQ0KeWVhcl90eXBlX3Bsb3RfZnJlcSA8LSB3ZWF0aGVyICU+JQ0KICBtdXRhdGUoeWVhciA9IHllYXIoU3RhcnRUaW1lKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHllYXIsIGZpbGwgPSBmY3RfaW5mcmVxKFR5cGUpKSkgKw0KICAgIGdlb21fYmFyKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UocHJlc2VydmUgPSAic2luZ2xlIikpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIlR5cGUgb3ZlciBZZWFyIikNCg0KZ2dwbG90bHkoeWVhcl90eXBlX3Bsb3RfZnJlcSkNCmBgYA0KDQoNCg0K